﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Zero.UControl.Base.Enums;

namespace Zero.UControl.Component
{
    public class SwitchTabControl : TabControl
    {
        private TranslateTransform _underlineTranslate;
        private ScaleTransform _underlineScale;
        private Rectangle _underline;
        private Canvas _canvas;


        static SwitchTabControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SwitchTabControl),
                new FrameworkPropertyMetadata(typeof(SwitchTabControl)));
        }

        #region 依赖属性
        public PlacementType Placement
        {
            get { return (PlacementType)GetValue(PlacementProperty); }
            set { SetValue(PlacementProperty, value); }
        }

        public static readonly DependencyProperty PlacementProperty =
            DependencyProperty.Register("Placement", typeof(PlacementType), typeof(SwitchTabControl), new PropertyMetadata(PlacementType.Bottom));

        #endregion


        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _underline = GetTemplateChild("PART_Underline") as Rectangle;
            _underlineTranslate = GetTemplateChild("PART_UnderlineTranslate") as TranslateTransform;
            _underlineScale = GetTemplateChild("PART_UnderlineScale") as ScaleTransform;
            _canvas = GetTemplateChild("PART_Canvas") as Canvas;

            this.SelectionChanged += OnSelectionChanged;
        }

        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_underline == null || _underlineTranslate == null || _underlineScale == null)
                return;

            if (this.ItemContainerGenerator.ContainerFromItem(this.SelectedItem) is TabItem selectedTab &&
                VisualTreeHelper.GetParent(selectedTab) is FrameworkElement container)
            {
                Point pos = selectedTab.TransformToAncestor(container).Transform(new Point(0, 0));
                double left = pos.X;
                double top = pos.Y;
                double width = selectedTab.ActualWidth;
                double height = selectedTab.ActualHeight;

                // 跳过初始化动画
                if (_underline.Width == 0)
                {
                    _underlineTranslate.X = left;
                    _underline.Width = width;
                    return;
                }
                if(_underline.Height == 0)
                {
                    _underlineTranslate.Y = top;
                    _underline.Height = height;
                    return;
                }

                switch (Placement)
                {
                    case PlacementType.Top:
                        HorizontalAnimateUnderline(left, width);
                        break;
                    case PlacementType.Bottom:
                        HorizontalAnimateUnderline(left, width);
                        break;
                    case PlacementType.Left:
                        VerticalAnimateUnderline(top, height);
                        break;
                    case PlacementType.Right:
                        VerticalAnimateUnderline(top, height);
                        break;
                    default:
                        break;
                }
       
            }
        }

        #region 水平方向处理逻辑
        private void HorizontalAnimateUnderline(double targetLeft, double targetWidth)
        {
            double currentLeft = _underlineTranslate.X;
            double currentWidth = _underline.Width;

            if (targetLeft > currentLeft)
                AnimateFixedLeft(targetLeft, targetWidth, currentLeft, currentWidth);
            else
                AnimateFixedRight(targetLeft, targetWidth, currentLeft, currentWidth);
        }

        /// <summary>
        /// 固定左方，向右进行拉伸，然后固定右方，进行收缩
        /// </summary>
        /// <param name="targetLeft"></param>
        /// <param name="targetWidth"></param>
        /// <param name="currentLeft"></param>
        /// <param name="currentWidth"></param>
        private void AnimateFixedLeft(double targetLeft, double targetWidth, double currentLeft, double currentWidth)
        {
            double targetRight = targetLeft + targetWidth;
            double scale = (targetRight - currentLeft) / currentWidth;

            _underline.RenderTransformOrigin = new Point(0, 0.5);
            _underlineTranslate.X = currentLeft;

            var expand = new DoubleAnimation(scale, TimeSpan.FromMilliseconds(200)) { EasingFunction = new CubicEase() };
            expand.Completed += (s, e) =>
            {
                _underline.RenderTransformOrigin = new Point(1, 0.5);
                _underlineTranslate.X = targetLeft;
                _underline.Width = targetWidth;

                var shrink = new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(200)) { EasingFunction = new CubicEase() };
                _underlineScale.BeginAnimation(ScaleTransform.ScaleXProperty, shrink);
            };
            _underlineScale.BeginAnimation(ScaleTransform.ScaleXProperty, expand);
        }

        /// <summary>
        /// 固定右方，向左进行拉伸，然后固定左方，进行收缩
        /// </summary>
        /// <param name="targetLeft"></param>
        /// <param name="targetWidth"></param>
        /// <param name="currentLeft"></param>
        /// <param name="currentWidth"></param>
        private void AnimateFixedRight(double targetLeft, double targetWidth, double currentLeft, double currentWidth)
        {
            double currentRight = currentLeft + currentWidth;
            double scale = (currentRight - targetLeft) / currentWidth;

            _underline.RenderTransformOrigin = new Point(1, 0.5);
            _underlineTranslate.X = currentLeft;

            var expand = new DoubleAnimation(scale, TimeSpan.FromMilliseconds(200)) { EasingFunction = new CubicEase() };
            expand.Completed += (s, e) =>
            {
                _underline.RenderTransformOrigin = new Point(0, 0.5);
                _underlineTranslate.X = targetLeft;
                _underline.Width = targetWidth;

                var shrink = new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(200)) { EasingFunction = new CubicEase() };
                _underlineScale.BeginAnimation(ScaleTransform.ScaleXProperty, shrink);
            };
            _underlineScale.BeginAnimation(ScaleTransform.ScaleXProperty, expand);
        }
        #endregion

        #region 竖直方向处理逻辑
        private void VerticalAnimateUnderline(double targetTop, double targetHeight)
        {
            double currentTop = _underlineTranslate.Y;
            double currentHeight = _underline.Height;

            if (targetTop > currentTop)
            {
                AnimateFixedTop(targetTop, targetHeight, currentTop, currentHeight);
            }
            else
            {
                AnimateFixedBottom(targetTop, targetHeight, currentTop, currentHeight);
            }
        }

        /// <summary>
        /// 固定上方，向下进行拉伸，然后固定下方，进行收缩
        /// </summary>
        /// <param name="targetTop"></param>
        /// <param name="targetHeight"></param>
        /// <param name="currentTop"></param>
        /// <param name="currentHeight"></param>
        private void AnimateFixedTop(double targetTop, double targetHeight, double currentTop, double currentHeight)
        {
            double targetBottom = targetTop + targetHeight;
            double scale = (targetBottom - currentTop) / currentHeight;

            _underline.RenderTransformOrigin = new Point(0.5, 0);
            _underlineTranslate.Y = currentTop;

            var expand = new DoubleAnimation(scale, TimeSpan.FromMilliseconds(200)) { EasingFunction = new CubicEase() };
            expand.Completed += (s, e) =>
            {
                _underline.RenderTransformOrigin = new Point(0.5, 1);
                _underlineTranslate.Y = targetTop;
                _underline.Height = targetHeight;

                var shrink = new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(200)) { EasingFunction = new CubicEase() };
                _underlineScale.BeginAnimation(ScaleTransform.ScaleYProperty, shrink);
            };
            _underlineScale.BeginAnimation(ScaleTransform.ScaleYProperty, expand);
        }

        /// <summary>
        /// 固定下方，向上进行拉伸，然后固定上方，进行收缩
        /// </summary>
        /// <param name="targetTop"></param>
        /// <param name="targetHeight"></param>
        /// <param name="currentTop"></param>
        /// <param name="currentHeight"></param>
        private void AnimateFixedBottom(double targetTop, double targetHeight, double currentTop, double currentHeight)
        {
            double currentBottom = currentTop + currentHeight;
            double scale = (currentBottom - targetTop) / currentHeight;

            _underline.RenderTransformOrigin = new Point(0.5, 1);
            _underlineTranslate.Y = currentTop;

            var expand = new DoubleAnimation(scale, TimeSpan.FromMilliseconds(200)) { EasingFunction = new CubicEase() };
            expand.Completed += (s, e) =>
            {
                _underline.RenderTransformOrigin = new Point(0.5, 0);
                _underlineTranslate.Y = targetTop;
                _underline.Height = targetHeight;

                var shrink = new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(200)) { EasingFunction = new CubicEase() };
                _underlineScale.BeginAnimation(ScaleTransform.ScaleYProperty, shrink);
            };
            _underlineScale.BeginAnimation(ScaleTransform.ScaleYProperty, expand);
        }
        #endregion

    }
}
